/**
 *@fileOverview This script aids in the creation of pictures placed within a
 *Polaroid (tm) border with an optional caption.
 *
 *@author Collin Brooks collin.brooks@gmail.com
 *@version 1
 */

/*jslint white: true, onevar: true, undef: true, nomen: true, eqeqeq: true,
plusplus: true, bitwise: true, regexp: true, newcap: true,
immed: true, maxlen: 80 */

// TODO
// -Batch mode
// -Edit an already created Polarad
// -Constrain picture proportions
// -Preferences
// -Allow the picture size to be based upon % as well as px
// -Allow the source dropdown menus to be based within a folder instead of the
// entire item list.



//This script utilizes and extends the COB object. If the COB object is not
//defined, define it.


//Import the COB include
COB = undefined;
$.evalFile(new File(new File($.fileName).path + "/COB_v1.jsxinc"));

$.localize = true;

COB.LOG.debug("Beginning PRad Object Init.");
/**
 * The Polarad object.
 * This object is the main namespace for the COB Polarad script and contains all
 * functions and properties that the Polaroid Maker requires in order to
 * function. It is placed within the COB object in order to preserve the
 * global namespace.
 * @constructor
 * @namespace
 */
COB.PRad = {};

/**
 *The name of this script
 *@type String
 */
COB.PRad.scriptName = "COB - Polarad";

/**
 *The string representation of the version of this script
 *@type String
 */
COB.PRad.scriptVersion = "v1";

/**
 *The file name of this script
 *@type String
 */
COB.PRad.scriptFileName = "COB_Polarad.jsx";

/**
 *The description of this script
 *@type String
 */
COB.PRad.scriptDescription = "This script aids in the creation of " +
    "Polaroid(tm) picture borders with or without captions.";

/**
 *A list of errors for the PRad script
 */
COB.PRad.error = {
    NO_OPENED_PROJECT: "You do not have a project open. Please open a project" +
        " before attempting to create a polarad.",
    NO_ACTIVE_COMPOSITION: "You do not currently have an active composition " +
        "selected. Please select a composition to place the polarad in.",
    NAME_NOT_DEFINED: "Please give your polarad a name.",
    PICTURE_SOURCE_NOT_FOUND: "The picture source you selected cannot be " +
        "found! Please refresh the list of available items.",
    BORDER_SOURCE_NOT_FOUND: "The border source you selected cannot be found!" +
        " Please refresh the list of available items."
};

/**
 *The current composition that is active
 *@type CompItem
 */
COB.PRad.currentComp = {};

/**
 *An array of currently selected layers within the active composition
 *@type {LayerItems[]}
 */
COB.PRad.selectedLayers = {};

/**
 *The currently selected picture source item
 *@type {AVItem|CompItem}
 */
COB.PRad.pictureSource = [];

/**
 *The currently selected border source item
 *@type {AVItem|CompItem}
 */
COB.PRad.borderSource = [];

/**
 *The default X size in pixels for the Polorad (not including the border)
 *@type {Number}
 */
COB.PRad.pictureSizeXDefault = 864;

/**
 *The default y size in pixels for the Polorad (not including the border)
 *@type {Number}
 */
COB.PRad.pictureSizeyDefault = 486;

/**
 *The default border padding in pixels for the Polorad
 *(not including the border)
 *@type {Number}
 */
COB.PRad.borderPaddingDefault = 3.5;

/**
 *The default pixel aspect ratio for the Polorad
 *@type {Number}
 */
COB.PRad.PARDefault = 1;

/**
 *The default frame rate for the Polorad's composition
 *@type {Number}
 */
COB.PRad.frameRateDefault = 29.97;

/**
 *The default duration (in seconds) for the Polorad's composition
 *@type {Number}
 */
COB.PRad.durationDefault = 6 * 60;

/**
 *Initiates the UI
 *@param {Object} thisObj The Window or Palette "this" used to determine whether
 *or not this UI should be set up as a Window or Palette.
 *@returns {Object} The PRad UI Object
 *@constructor
 *@see COB.PRad
 *@extends COB.PRad
 */

/**
 *Language strings used within this script
 */
COB.PRad.lang = {
    //Individual words
    "folderName": {en: "Polarads"},
    "Caption": {en: "Caption"},
    "Picture": {en: "Picture"},
    "Size": {en: "Size"},
    "Padding": {en: "Padding"},
    "Height": {en: "Height"},
    "by": {en: "by"},

    //Phrases
    "createPolarad": {en: "Create Polarad"},
    "windowName": {en: "COB - Polarad"},
    "polaradName": {en: "Polarad Name"},
    "setToPicName": {en: "Set to picture name"},
    "borderBackground": {en: "Border Background"},
    "newSolid": {en: "New Solid"},
    "finalPolaradSize": {en: "Final Polarad Size"},
    "refresh": {en: "R"},
    "help": {en: "?"},
    "undoGroupName": {en: "Undo Create Polarad"},
    "borderSolidSuffix": {en: "_borderSolid"},
    "pictureSolidSuffix": {en: "_pictureSolid"}
};

/**
 *The folder name to store the Polarad in.
 *@type {String}
 */
COB.PRad.folder = localize(COB.PRad.lang.folderName);


/**
 *Initializes the UI for the COB.PRad script.
 *@param {Window|Pallette} thisObj The Window or Palette Object that
 *this script is run in.
 *@constructor
 *@returns {Object} The COB.PRad.UI Object.
 */
COB.PRad.UI = (function (thisObj)
{
    COB.LOG.debug("Initializing UI");
    
    var that = this,

    ////////////////////////////////////////////////////////////////////////////
    // editView Shortcut Variable Declarations
    ////////////////////////////////////////////////////////////////////////////

    editViewBase,
    editView_nameGroup,
    editView_picturePanel,
    editView_pictureName,
    editView_linkName,
    editView_sourcesRow,
    editView_pictureSource,
    editView_refreshPictureSource,
    editView_pictureSizeX,
    editView_pictureSizeY,
    editView_borderPanel,
    editView_borderPadding,
    editView_borderSizeUnitPercent,
    editView_borderSource,
    editView_refreshBorderSource,
    editView_captionHeight,
    editView_captionRow,
    editView_caption,
    editView_captionOn,
    editView_buttonRow,
    editView_infoText,
    editView_helpButton,
    editView_createButton,

    ////////////////////////////////////////////////////////////////////////////
    // Misc. Variables
    ////////////////////////////////////////////////////////////////////////////

    res,
    darkPen,
    vConstructor,
    views,

    /**
     *The font format to use for symbol buttons
     *@type {ScriptUIFont}
     */
    symbolFont = ScriptUI.newFont("Arial", ScriptUI.FontStyle.BOLD, 10),

    //Language Strings
    lang = COB.PRad.lang,

    //Window/Panel setup
    myWindow = (thisObj instanceof Panel) ?
        thisObj :
        new Window("palette",
        COB.PRad.scriptName + " " + COB.PRad.scriptVersion,
        undefined,
        {
            "resizeable": false
        });

    COB.LOG.debug("Trying to add UI Res");

    //Add the resources for this window
    try {
        vConstructor = COB.UI_helper.viewsConstructor(myWindow,
            "orientation: 'stack', " +
            "margins: 0, " +
            "spacing: 10"
        );

        COB.LOG.debug("Main Window Group Added.");

        vConstructor.addView("newPolaradView",
            "alignment:['fill','fill']," +
            "orientation: 'column'," +
            "test: StaticText { text:'lorem ipsum'}"
        );

        COB.LOG.debug("View 'new' added.");

        vConstructor.addView("editPolaradView",
                "alignment:['fill','fill']," +
                "orientation: 'column'," +
                "nameGroup: Group {" +
                    "orientation: 'row', " +
                    "margins:[5,5,10,0], " +
                    "nameLabel: StaticText {" +
                        "text: '" + localize(lang.polaradName) + "'" +
                    "}," +
                    "name: EditText {alignment: ['fill','fill']}," +
                    "alignment: ['fill','fill']," +
                    "linkName: Checkbox {" +
                        "text: '" + localize(lang.setToPicName) + "'," +
                        "alignment: ['right', 'fill']," +
                        "value: true," +
                    "}," +
                "}," + //End nameGroup
                "sourcesRow: Group {" +
                    "orientation: 'row', " +
                    "margins:[5, 10, 5, 10], " +
                    "alignment:['fill','fill'], " +
                    "alignChildren: ['center', 'middle']," +
                    "picturePanel: Panel {" +
                        "text:'" + localize(lang.Picture) + "', " +
                        "alignment: ['fill','fill'], " +
                        "alignChildren:['left','middle'], " +
                        "margins: 10," +
                        "spacing: 0," +
                        "row1: Group {" +
                            "orientation: 'row', " +
                            //"alignment: ['fill','fill'], " +
                            "margins:0, " +
                            "source: ListBox {" +
                                "preferredSize: [225,100]" +
                            "}," +
                        "}," + //End row1
                        "buttonRow: Group {" +
                            "orientation: 'row'," +
                            "alignment: ['center','middle']," +
                            "spacing: 10," +
                            "margins: [0, 0, 0, 20]," +
                            "add: Button {" +
                                "text: '+'," +
                                "preferredSize: [20,20]," +
                            "}," +
                            "sub: Button {" +
                                "text: 'minus'," +
                                "preferredSize: [20,20]," +
                            "}," +
                            "clear: Button {" +
                                "text: 'c'," +
                                "preferredSize: [20,20]," +
                            "}," +
                            "refreshPictureSource: Button {" +
                                "preferredSize: [20,20], " +
                                "text: '" + localize(lang.refresh) + "'" +
                            "}" +
                        "}," + //End picture source buttonRow
                        "row2: Group {" +
                            "orientation: 'row', " +
                            "margins:0, " +
                            //"alignment: ['center','middle']," +
                            "sizeLabel: StaticText {" +
                                "text: '" +
                                localize(lang.Size) + ":'" +
                            "}," +
                            "editGroup: Group {" +
                                "orientation: 'row', " +
                                "margins:0, " +
                                //"alignment:['right','fill'], " +
                                "preferredSize: [150, 20]," +
                                "sizeX: EditText {text: '1920', " +
                                    "preferredSize:[40,20]" +
                                "}," +
                                "separator: StaticText {text: ' x '}," +
                                "sizeY: EditText {text: '1080', " +
                                    "preferredSize:[40,20]" +
                                "}," +
                                "pictureSizeUnitPercent: RadioButton {" +
                                    "text: '%'," +
                                    "value: true," +
                                "}," +
                                "pictureSizeUnitPx: RadioButton {" +
                                    "text: 'px'" +
                                "}," +
                            "}," + //End editGroup
                        "}," + //End row2
                    "}," + //End picturePanel
                    "borderPanel: Panel {" +
                        "text:'" + localize(lang.borderBackground) + "', " +
                        "alignment:['fill','fill'], " +
                        "margins: 10," +
                        "spacing: 0," +
                        "row1: Group {" +
                            "orientation: 'row', " +
                            "margins:0, " +
                            "alignment:['fill','fill'], " +
                            "borderSource: ListBox {" +
                                "margins: 0," +
                                "preferredSize:[225,100]" +
                            "}," +
                        "}," + //End row1
                        "buttonRow: Group {" +
                            "orientation: 'row'," +
                            "alignment: 'center'," +
                            "spacing: 10," +
                            "margins: [0, 0, 0, 20]," +
                            "preferredSize: [100,20]," +
                            "add: Button {" +
                                "text: '+'," +
                                "preferredSize: [20,20]," +
                            "}," +
                            "sub: Button {" +
                                "text: 'm'," +
                                "preferredSize: [20,20]," +
                            "}," +
                            "clear: Button {" +
                                "text: 'c'," +
                                "preferredSize: [20,20]," +
                            "}," +
                            "refreshBorderSource: Button {" +
                                "preferredSize: [20,20], " +
                                "text: '" + localize(lang.refresh) + "'" +
                            "}" +
                        "}," + //End background source buttonRow
                        "row2: Group {" +
                            "orientation: 'row', " +
                            "margins:0, " +
                            "alignment:['fill','fill'], " +
                            "sizeLabel: StaticText {" +
                                "text: '" +
                                localize(lang.Padding) +
                                ":'" +
                            "}," +
                            "borderPadding: EditText {" +
                                "text: '" +
                                    COB.PRad.borderPaddingDefault +
                                "', " +
                                "preferredSize:[40,20]" +
                            "}," +
                            "borderSizeUnitPercent: RadioButton {" +
                                "text: '%'," +
                                "value: true," +
                            "}," +
                            "borderSizeUnitPx: RadioButton {" +
                                "text: 'px'" +
                            "}," +
                        "}," + //End row2
                    "}," +//End borderPanel
                "}," + //End sourcesRow
                "captionRow: Group {" +
                    "orientation: 'row', " +
                    "margins:[10,0,10,0], " +
                    "alignment:['fill','fill'], " +
                    "alignChildren:['right','middle']," +
                    "captionOn: Checkbox {" +
                        "value: true," +
                        "alignment: ['left','middle']," +
                    "}," +
                    "captionLabel: StaticText {" +
                        "text: '" + localize(lang.Caption) + ":', " +
                        "alignment:['left', 'middle']," +
                    "}," +
                    "caption: EditText {" +
                        "preferredSize: [150,20], " +
                        "alignment:['fill','middle']" +
                    "}," +
                    "heightLabel: StaticText {" +
                        "text: '" + localize(lang.Height) + " (px):'" +
                    "}," +
                    "height: EditText {" +
                        "text: '100', " +
                        "preferredSize: [30,20]" +
                    "}," +
                "}," + //End captionRow
                "buttonRow: Group {" +
                    "orientation: 'row', " +
                    "margins:[10,20,10,10], " +
                    "alignment:['fill','fill'], " +
                    "alignChildren:['right','fill']," +
                    "infoText: StaticText {" +
                        "preferredSize: [100,20]," +
                        "text:' ', " +
                        "alignment: ['fill','left']" +
                    "}," +
                    "helpButton: Button {" +
                        "text:'" + localize(lang.help) + "'," +
                        "preferredSize:[20,20]" +
                    "}," +
                    "createButton: Button {text:'" +
                    localize(lang.createPolarad) +
                    "'}," +
                "}," //End buttonRow
        );

        //Build the window
        myWindow = vConstructor.build();

        //Give access to this UI's views to the outside world
        views = vConstructor.getViews();
        COB.LOG.debug("View 'edit' added.");

    } catch (e) {
//        throw(e);
        COB.UI_helper.resError(e, res);
    }

    //Have the layout calculate the position of its resources.
    myWindow.layout.layout(true);
    myWindow.onResizing = myWindow.onResize = function () {
        this.layout.resize();
    };

    /**
     *Displays the window or palette. If it is a window, it is centered,
     *otherwise, the layout() function is called on the palette.
     *@returns Nothing.
     */
    this.display = function () {
        if (myWindow !== null)
        {
            if (myWindow instanceof Window)
            {
                myWindow.center();
                myWindow.show();
            } else {
                myWindow.layout.layout(true);
            }
            vConstructor.showView('editPolaradView');
        }
    };

    COB.LOG.debug("Assigning shortcut variables");

    ////////////////////////////////////
    //Edit View Shortcut Variables
    ////////////////////////////////////

    editViewBase = views.editPolaradView;

    //Name Group
    editView_nameGroup = editViewBase.nameGroup;

    editView_pictureName        = editView_nameGroup.name;
    editView_linkName           = editView_nameGroup.linkName;

    //Sources Row
    editView_sourcesRow = editViewBase.sourcesRow;

    //Picture Panel
    editView_picturePanel = editView_sourcesRow.picturePanel;

    editView_pictureSource          = editView_picturePanel.row1.source;
    editView_pictureButtonRow       = editView_picturePanel.buttonRow;
    editView_refreshPictureSource   = editView_pictureButtonRow.
                                        refreshPictureSource;
    editView_addPictureSource       = editView_pictureButtonRow.add;
    editView_subPictureSource       = editView_pictureButtonRow.sub;
    editView_clearPictureSource     = editView_pictureButtonRow.clear;
    editView_pictureSizeX           = editView_picturePanel.row2.editGroup.
                                        sizeX;
    editView_pictureSizeY           = editView_picturePanel.row2.editGroup.
                                        sizeY;

    //Border Panel
    editView_borderPanel = editView_sourcesRow.borderPanel;

    editView_borderPadding          = editView_borderPanel.row2.borderPadding;
    editView_borderSizeUnitPercent  = editView_borderPanel.row2.
                                        borderSizeUnitPercent;
    editView_borderSource           = editView_borderPanel.row1.borderSource;
    editView_borderButtonRow        = editView_borderPanel.buttonRow;
    editView_addBorderSource        = editView_borderButtonRow.add;
    editView_subBorderSource        = editView_borderButtonRow.sub;
    editView_clearBorderSource      = editView_borderButtonRow.clear;
    editView_refreshBorderSource    = editView_borderPanel.buttonRow.
                                        refreshBorderSource;

    //Caption Row
    editView_captionRow = editViewBase.captionRow;

    editView_captionHeight          = editView_captionRow.height;
    editView_captionOn              = editView_captionRow.captionOn;
    editView_caption                = editView_captionRow.caption;

    //Button Row
    editView_buttonRow = editViewBase.buttonRow;

    editView_infoText               = editView_buttonRow.infoText;
    editView_helpButton             = editView_buttonRow.helpButton;
    editView_createButton           = editView_buttonRow.createButton;

    ////////////////////////////////////////////////////////////////////////////
    // Public editView Methods
    ////////////////////////////////////////////////////////////////////////////

    /**
     * The editView object contains all of the methods required by the edit view
     * of this UI.
     * @type {Object}
     */
    this.editView = {};

    //GETTERS
    
    /**
     *Returns the name of the polarad from the "Name" field.
     *@returns {String}
     */
    this.editView.getPolaradName = function () {
        return editView_pictureName.text;
    };

    /**
     *Returns an array of ListItems selected for use as picture sources or null
     *if a source is not selected.
     *@returns {ListItem[]} An array of ListItems that the user has selected.
     */
    this.editView.getPictureSourceSelection = function () {
        return (editView_pictureSource.selection !== null) ?
            editView_pictureSource.selection: null;
    };

    /**
     *Returnes the X size of the picture as an INT
     *@returns {Number} The number of Y pixels that
     *the picture should be sized at.
     */
    this.editView.getPictureSizeX = function () {
        return parseInt(editView_pictureSizeX.text, 10);
    };

    /**
     *Returns the Y size of the picture as an INT
     *@returns {Number} The number of X pixels that
     *the picture should be sized at.
     */
    this.editView.getPictureSizeY = function () {
        return parseInt(editView_pictureSizeY.text, 10);
    };

    /**
     *Returns the amount of pixels that should pad the outside of the picture
     *and have the background show through.
     *@returns {Number} The number of pixels to pad the outside of the
	 *picture with.
     */
    this.editView.getBorderPadding = function () {
        return parseInt(editView_borderPadding.text, 10);
    };

    /**
     *Gets the unit that the border is to be calculated as.
     *@returns {String} "%" if the unit is percent and "px"
     *if the unit is pixels.
     */
    this.editView.getPaddingUnit = function () {
        return (editView_borderSizeUnitPercent.value) ? "%" : "px";
    };

    /**
     *Returns an array of ListItems selected for the border or null if a source
     *is not selected.
     *@returns {ListItem[]} An array of ListItems that the user has selected.
     */
    this.editView.getBorderSourceSelection = function () {
        return (editView_borderSource.selection !== null) ?
            editView_borderSource.selection: null;
    };

    /**
     *Returns the heigh in pixels to make the caption section of the polaroid.
     *If the caption is not enabled, 0 is returned.
     *@returns {Number}
     */
    this.editView.getCaptionHeight = function () {
        if (that.editView.getCaptionState())
        {
            return parseInt(editView_captionHeight.text, 10);
        } else {
            return 0;
        }
    };

    /**
     *Returns the text to be used as the caption of this polaroid.
     *@returns {String}
     */
    this.editView.getCaption = function () {
        return editView_caption.text;
    };

    /**
     *Returns the state of the captionOn checkbox
     *@returns {Bool}
     */
    this.editView.getCaptionState = function () {
        return editView_captionOn.value;
    };



    // SETTERS



    /**
     *Sets the info text.
     *@param {String} t The text to be displayed in the infoText StaticText
     *object.
     *@returns Nothing.
     */
    this.editView.setInfo = function (t) {
        editView_infoText.text = t;
    };

    /**
     *Sets the name of the picture from the "Name" field.
     *@param {String} n The name to be placed in the "Name" field.
     */
    this.editView.setPictureName = function (n) {
        editView_pictureName.text = n;
    };

    /**
     *Populates the picture or border source List Boxes with the provided
     *array while keeping the currently selected items intact.
     *@param {String} t The source list to modify. Either 'picture' or 'border'.
     *@param {Item[]} l An array of project Items with the type 'Footage' or
     *'Composition' to set as the list items in the dropdown menu.
     *@returns Nothing.
     */
    this.editView.setSourceLists = function (l) {

        var prevSelSources, list, item, currItem, f;

        //Make the source list type lowercase
        t = t.toLowerCase();

        if (t === 'picture') {
            prevSelSources = that.editView.getPictureSourceSelection();
            list = editView_pictureSource;
            f = that.editView.setFolderSource;
        } else if (t === 'border') {
            prevSelSources = that.editView.getBorderSourceSelection();
            list = editView_pictureSource;
            f = that.editView.setFolderSource;
        } else {
            throw (new Error("TypeError: Unexpected value " + t + ". Expected" +
                " 'picture' or  'border'"));
        }

        //Remove all items from the lists
        list.removeAll();

        //Add the solid and a divider to both lists
//        editView_pictureSource.add("item", localize(lang.newSolid));
//        editView_pictureSource.add("separator");
//
//        editView_borderSource.add("item", localize(lang.newSolid));
//        editView_borderSource.add("separator");

        for (item in l)
        {

            if (l[item].typeName === "Composition" ||
                l[item].typeName === "Footage") {
                currItem = list.add("item", l[item].name);
                currItem.data = {
                    "typeName": l[item].typeName,
                    "itemRef": l[item]
                };
            }
        }

        //Set the previously selected sources
        f(prevSelSources);
    };

    /**
     *Sets the X size of the picture
     *@param {Number} n The amount of pixels for the X size of the picture.
     */
    this.editView.setPictureSizeX = function (n) {
        editView_pictureSizeX.text = n;
    };

    /**
     *Sets the Y size of the picture as an INT
     *@param {Number} n The number of Y pixels that the picture should be
     *sized at.
     */
    this.editView.setPictureSizeY = function (n) {
        editView_pictureSizeY.text = n;
    };

    /**
     *Sets the amount of pixels that should pad the outside of the picture
     *and have the background show through.
     *@param {Number} n The number of pixels to pad the outside of the picture
	 *with.
     */
    this.editView.setBorderPadding = function (n) {
        editView_borderPadding.text = n;
    };

    /**
     *Sets the height in pixels to make the caption section of the polaroid.
     *@param {Number} n The number of pixels to set as the caption height.
     */
    this.editView.setCaptionHeight = function (n) {
        editView_captionHeight.text = n;
    };

    /**
     *Sets the text to be used as the caption of this polaroid.
     *@param {String}
     *@returns Nothing.
     */
    this.editView.setCaption = function (c) {
        editView_caption.text = c;
    };

    /**
     *Sets the state of the captionOn checkbox.
     *@param {Bool} s True for checked and false for unchecked.
     *@returns Nothing.
     */
    this.editView.setCaptionState = function (s) {
        editView_captionOn.value = s;
    };

    //DELETERS

    /**
     *Removes the selected item(s) from the specified ListBox.
     *@param {String} t The ListBox to target. One of 'picture' or 'border'.
     *@param {Bool} [conf=false]
     *@returns Nothing
     */
     this.editView.deleteListSelection = function (t, conf) {
        if (t !== 'picture' || t !== 'border') {
            throw(new Error("ValueError: Unexpected value '" + t + "', Expected " +
                "'picture' or 'border'."));
        }

        var i, list, sel;

        //If conf is not set, make it false
        conf = conf || false;

        //If conf is true and the user confirms, conf is true
        if (conf && confirm('Remove the selected ' + t + "s?")) {
            conf = true;
        //otherwise, conf is false
        } else {
            conf = false;
        }

        //Did we have confirmation?
        if (conf) {

            if (t === 'picture') {
                list = editView_pictureSource;
            } else if (t === 'border') {
                list = editView_borderSource;
            }

            sel = list.selection;
            for (item in sel) {
                if (item instanceof ListItem) {
                    list.remove(item);
                }
            }
        }
     };

    //Event Handlers

    /**
     *Sets the handlers for when the "Create" button is clicked
     *@param {Function} f The function to call when the "Create" button
	 *is clicked
     *@returns Nothing.
     */
    this.editView.onCreatePolarad = function (f) {
        editView_createButton.onClick = f;
    };

    /**
     *Sets the handler for when the refreshPictureSource button is clicked
     *@param {Function} f The function to call when the refreshPictureSource
     *button is clicked
     *@returns Nothing.
     */
    this.editView.onPictureSourceRefresh = function (f) {
        editView_refreshPictureSource.onClick = f;
    };

    /**
     *Sets the handler for when the refreshBorderSource button is clicked
     *@param {Function} f The function to call when the refreshBorderSource
     *button is clicked
     *@returns Nothing.
     */
    this.editView.onBorderSourceRefresh = function (f) {
        editView_refreshBorderSource.onClick = f;
    };

    /**
     *Sets the handler for when the add button is clicked under the picture
     *source ListBox.
     *@param {Function} f The function to call
     *@returns Nothing.
     */
    this.editView.onAddPictureSource = function (f) {
        editView_addPictureSource.onClick = f;
    };

    /**
     *Sets the handler for when the add button is clicked under the border
     *source ListBox.
     *@param {Function} f The function to call.
     *@returns Nothing.
     */
    this.editView.onAddBorderSource = function (f) {
        editView_addBorderSource.onClick = f;
    };

    /**
     *Sets the handler for when the help button is clicked
     *@param {Function} f The function to call when the help
     *button is clicked
     *@returns Nothing.
     */
    this.editView.onHelpButtonClick = function (f) {
        editView_helpButton.onClick = f;
    };

    /**
     *Sets the info to the final size of the polarad
     *@returns Nothing.
     *@requires COB.Prad.pictureSource
     */
    this.editView.updateSizeInfo = function () {
        var picX = that.editView.getPictureSizeX(),
            picY = that.editView.getPictureSizeY(),
            pad = that.editView.getBorderPadding(),
            padUnit = that.editView.getPaddingUnit(),
            capHeight = that.editView.getCaptionHeight(),
            p = COB.PRad.pictureSource,
            finalSizeX,
            finalSizeY,
            info;

        //Figure out border padding if it is percent
        if (padUnit === "%") {
            pad = (picX * (pad / 100)).toPrecision(2);
        }

        finalSizeX = picX + (pad * 2);
        finalSizeY = picY + (pad * 2);

        //Include the caption height if it is enabled.
        finalSizeY += capHeight;

        info = localize(lang.finalPolaradSize) + ": " +
            finalSizeX + "px " + localize(lang.by) + " " +
            finalSizeY + "px";

        if (p && p.pixelAspect !== 1) {
            info += (p.pixelAspect) ? " (" + p.pixelAspect + " PAR)" : "";
        }

        that.editView.setInfo(info);
    };

    /**
     *Updates the picture dimensions based on the size of the selected picture
     *source.
     *@param {AVItem} p The picture source item to get the width and height from
     *@returns Nothing.
     *@private
     */
    this.editView.setPictureDimensions = function (p) {
        if (p) {
            that.editView.setPictureSizeX(p.width);
            that.editView.setPictureSizeY(p.height);
        }

        //Update the info text
        that.editView.updateSizeInfo();
    };

    /**
     *Sets the name of the Polarad to be that of the selected picture source
     *if the linkName checkbox is checked.
     *@returns Nothing.
     *@private
     */
    this.editView.setNameIfLinked = function () {
        if (editView_linkName.value) {
            editView_pictureName.text = that.editView.getPictureSourceName();
        }
    };

    //Setup event functions that are controlled by the UI

    editView_captionOn.onClick = function () {
        var e = editView_captionOn.value;
        editView_caption.enabled = e;
        editView_captionHeight.enabled = e;

        //Update the info text
        that.editView.updateSizeInfo();
    };

    editView_subPictureSource.onClick = function () {
        that.editView.deleteListItemSelection('picture', true);
    };

    editView_subBorderSource.onClick = function () {
        that.editView.deleteListItemSelection('border', true);
    };

    editView_clearPictureSource.onClick = function () {
        editView_pictureSource.removeAll();
    };

    editView_clearBorderSource.onClick = function () {
        editView_borderSource.removeAll();
    };

    editView_linkName.onClick = this.editView.setNameIfLinked;

    editView_pictureSizeX.onChange  = this.editView.updateSizeInfo;
    editView_pictureSizeY.onChange  = this.editView.updateSizeInfo;
    editView_borderPadding.onChange = this.editView.updateSizeInfo;
    editView_captionHeight.onChange = this.editView.updateSizeInfo;

    editView_pictureSource.onChange = function () {
        COB.PRad.pictureSource = COB.PROJ_helper.getItemByName(
            that.editView.getPictureSourceName()
        );

        that.editView.setPictureDimensions(COB.PRad.pictureSource);
        that.editView.setNameIfLinked();
    };

    editView_borderSource.onChange = function () {
        COB.PRad.borderSource = COB.PROJ_helper.getItemByName(
            that.editView.getBorderSourceName()
        );
    };


    //Setup Graphic Specifications
    darkPen = myWindow.graphics.newPen(
                myWindow.graphics.PenType.SOLID_COLOR,
                [0, 0, 0, 1], 1);

    editView_pictureName.graphics.foregroundColor = darkPen;
    editView_pictureSource.graphics.foregroundColor = darkPen;
    editView_pictureSizeX.graphics.foregroundColor = darkPen;
    editView_pictureSizeY.graphics.foregroundColor = darkPen;
    editView_borderPadding.graphics.foregroundColor = darkPen;
    editView_borderSource.graphics.foregroundColor = darkPen;
    editView_captionHeight.graphics.foregroundColor = darkPen;
    editView_caption.graphics.foregroundColor = darkPen;

    //Fonts

    editView_refreshPictureSource.graphics.font = symbolFont;
    editView_refreshBorderSource.graphics.font = symbolFont;

    COB.LOG.debug("Returning UI Object");
    return this;
}(this)); // End COB.PRad.UI



/*------------------------------------------------------------------\
    COB.PRad METHODS
\------------------------------------------------------------------**/



COB.LOG.debug("Defining PRad Methods");
/**
 *Displays help information to the user
 *@returns Nothing.
 */
COB.PRad.help = function () {
    COB.LOG.debug("COB.PRad.help called");
    alert("Help Documentation");
};

/**
 *Creates a polarad based upon information collected from the UI
 *@returns Nothing.
 */
COB.PRad.createPolarad = function () {

    COB.LOG.debug("COB.PRad.createPolarad called");

    //Gather the information from the UI
    var lang = COB.PRad.lang,
        editView                = COB.PRad.UI.views.edit,
        name                    = editView.getPolaradName(),
        pictureSourceName       = editView.getPictureSourceName(),
        pictureIsSolid          = (pictureSourceName === localize(
                                    lang.newSolid)) ?
                                    true : false,
        pictureSizeX            = editView.getPictureSizeX(),
        pictureSizeY            = editView.getPictureSizeY(),
        caption                 = editView.getCaption(),
        captionOn               = editView.edit.getCaptionState(),
        captionHeight           = editView.getCaptionHeight(),
        borderSourceName        = editView.edit.getBorderSourceName(),
        borderIsSolid           = (borderSourceName === localize(
                                    lang.newSolid)) ?
                                    true : false,
        borderPadding           = editView.getBorderPadding(),
        borderPaddingUnit       = editView.getPaddingUnit(),
        proj                    = COB.PROJ_helper.getProject(),
        currentComp             = COB.PROJ_helper.getActiveComp(),

        //Preference Defaults
        pictureSizeXDefault     = COB.PRad.pictureSizeXDefault,
        pictureSizeYDefault     = COB.PRad.pictureSizeYDefault,
        borderPaddingDefault    = COB.PRad.borderPaddingDefault,
        frameRate               = COB.PRad.frameRateDefault,
        duration                = COB.PRad.durationDefault,
        folder                  = COB.PRad.folder,
        fName                   = folder,

        newSolidColor           = [0, 0, 0], //Black

        error                   = "",

        //Var values set later
        compWidth,
        compHeight,
        polaradComp,
        polaradBorder,
        polaradPicture,
        captionLayer,
        borderSource,
        pictureSource,
        borderSourcePAR,
        pictureSourcePAR;

    //Perform some error checking before we begin...

    //Do we have an active project?
    COB.LOG.debug("Active Project: " + (proj !== false));
    if (proj === false)
    {
        error += COB.PRad.error.NO_OPENED_PROJECT + "\n";
    }

    //Do we have an active composition?
//    COB.LOG.debug("Current Composition Set: " + currentComp.name);
//    if (currentComp === false)
//    {
//        error += COB.PRad.error.NO_ACTIVE_COMPOSITION + "\n";
//    }

    //The Polarad needs a name!
    COB.LOG.debug("Polarad Name: " + name);
    if (name === "")
    {
        error += COB.PRad.error.NAME_NOT_DEFINED + "\n";
    }

    //Verify the picture source is actually defined
    if (!pictureIsSolid)
    {
        COB.LOG.debug("Picture Source Defined: " +
            (COB.PROJ_helper.itemExists(pictureSourceName)));
        if (!COB.PROJ_helper.itemExists(pictureSourceName))
        {
            error += COB.PRad.error.PICTURE_SOURCE_NOT_FOUND + "\n";
        }
    }

    //Verify the borderSource is actually defined
    if (!borderIsSolid)
    {
        COB.LOG.debug("Border Source Defined: " +
            (COB.PROJ_helper.itemExists(borderSourceName)));
        if (!COB.PROJ_helper.itemExists(borderSourceName))
        {
            error += COB.PRad.error.BORDER_SOURCE_NOT_FOUND + "\n";
        }
    }

    //Moment of truth...
    if (error !== "")
    {
        COB.LOG.debug("Error Found. Exiting");
        COB.alertError({
            name: "PolaradCreationError",
            message: error,
            fileName: COB.PRad.fileName
        });
    } else {

        //Set defaults if they aren't already set
        pictureSizeX = (isNaN(pictureSizeX)) ?
            pictureSizeXDefault :
            pictureSizeX;
        pictureSizeY = (isNaN(pictureSizeY)) ?
            pictureSizeYDefault :
            pictureSizeY;
        borderPadding = (isNaN(borderPadding)) ?
            borderPaddingDefault : borderPadding;

        //Gather sources
        borderSource = COB.PRad.borderSource;
        pictureSource = COB.PRad.pictureSource;
        folder = COB.PROJ_helper.getFolderByName(fName);

        pictureSourcePAR = (!pictureIsSolid) ?
            pictureSource.pixelAspect :
            COB.PRad.PARDefault;
        borderSourcePAR = (!borderIsSolid) ?
            borderSource.pixelAspect :
            COB.PRad.PARDefault;

        COB.LOG.debug("Error Checks Passed");

        app.beginUndoGroup(localize(lang.undoGroupName) + " " + name);

        //Create the Polarad folder if it isn't already defined

        if (folder === null)
        {
            COB.LOG.debug("Adding Folder: " + fName);
            folder = proj.items.addFolder(fName);
        }


        try {

            //If the border padding unit is percent, calculate border padding
            if (borderPaddingUnit === "%") {
                borderPadding = (
                    pictureSizeX * (borderPadding / 100)
                ).toPrecision(2);
            }

            //Create a new composition with the proper dimensions
            compWidth = pictureSizeX + (borderPadding * 2);

            COB.LOG.debug("Comp Width: " + compWidth);

            compHeight = pictureSizeY + (borderPadding * 2);

            COB.LOG.debug("Comp Height: " + compHeight);

            //If the caption is disabled, captionHeight is 0 so this will
            //have no effect.
            compHeight += captionHeight;

            polaradComp = proj.items.addComp(name,
                                Math.round(compWidth),
                                Math.round(compHeight),
                                pictureSourcePAR,
                                duration,
                                frameRate
                            );

            //Move the composition into the Polarads folder
            COB.LOG.debug("Moving Polarad into folder");

            polaradComp.parentFolder = folder;

            COB.LOG.debug("Composition Created");

            //Place border source
            if (!borderIsSolid)
            {
                polaradBorder = polaradComp.layers.add(
                    borderSource,
                    duration
                );

            } else {
                polaradBorder = polaradComp.layers.addSolid(
                    newSolidColor,
                    name + localize(lang.borderSolidSuffix),
                    compWidth,
                    compHeight,
                    borderSourcePAR,
                    duration
                );
            }

            //Set the border's comment to signify that it is a polarad border
            polaradBorder.comment = "Polarad: Border";

            COB.LOG.debug("Border Source Placed");

            //Set scale in %
            if (!borderIsSolid) {
                polaradBorder.scale.setValue([
                    (
                        (compWidth * pictureSourcePAR) /
                        (polaradBorder.width * borderSourcePAR)
                    ) * 100,
                    (compHeight / polaradBorder.height) * 100
                ]);
            }

            polaradBorder.position.setValue([compWidth / 2, compHeight / 2]);

            //Place picture source
            if (!pictureIsSolid) {
                polaradPicture = polaradComp.layers.add(
                    pictureSource,
                    duration
                );
            } else {
                polaradPicture = polaradComp.layers.addSolid(
                    newSolidColor,
                    name + localize(lang.pictureSolidSuffix),
                    pictureSizeX,
                    pictureSizeY,
                    pictureSourcePAR,
                    duration
                );
            }

            //Set the picture's comment to signify that it is a polarad picture
            polaradPicture.comment = "Polarad: Picture";

            //Set scale in %
            if (!pictureIsSolid) {
                polaradPicture.scale.setValue([
                    (pictureSizeX / polaradPicture.width * 100),
                    (pictureSizeY / polaradPicture.height * 100)
                ]);
            }

            polaradPicture.position.setValue([
                polaradPicture.position.value[0],
                (
                    +(borderPadding) + (
                        (polaradPicture.height *
                            (polaradPicture.scale.value[1] / 100)
                        ) / 2
                    )
                )
            ]);

            //Place Caption (if any)
            if (captionOn)
            {
                captionLayer = polaradComp.layers.addText(
                            caption
                            );

                COB.LOG.debug("Caption: " + caption);

                captionLayer.position.setValue([captionLayer.position.value[0],
                            compHeight - (captionHeight / 2)]);
                captionLayer.comment = "Polarad: Caption";
            }


            //Insert the created Polarad into the currently active composition
            //currentComp.layers.add(polaradComp);

            COB.LOG.debug("Polarad creation complete");

        } catch (e) {

            COB.alertError("PolaradCreationError: " +
                "Could not create polarad because of error:",
                e);
        }

        app.endUndoGroup();
    }
};



/*------------------------------------------------------------------\
    COB.PRad MAIN
\------------------------------------------------------------------**/

//Write the script start time
COB.LOG.insertLogStart(COB.PRad.scriptName);

COB.PRad.UI.editView.setSourceLists(
    COB.PROJ_helper.getItemList(['Composition', 'Footage'])
);

COB.PRad.UI.editView.updateSizeInfo();

//Setup UI event handlers
COB.PRad.UI.editView.onPictureSourceRefresh(
    function () {
        COB.PRad.UI.editView.setSourceLists(
            COB.PROJ_helper.getItemList(['Composition', 'Footage'])
        );
    });

COB.PRad.UI.editView.onBorderSourceRefresh(
    function () {
        COB.PRad.UI.editView.setSourceLists(
            COB.PROJ_helper.getItemList(['Composition', 'Footage'])
        );
    });

COB.PRad.UI.editView.onHelpButtonClick(COB.PRad.help);

COB.PRad.UI.editView.onCreatePolarad(COB.PRad.createPolarad);

//Display the UI
COB.PRad.UI.display();